package com.yanfan.jksh;

import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.yanfan.base.session.Session;
import com.yanfan.common.annotation.SysProtocol;
import com.yanfan.common.constant.YanfanConstant;
import com.yanfan.common.core.mq.DeviceReport;
import com.yanfan.common.core.mq.MQSendMessageBo;
import com.yanfan.common.core.mq.message.DeviceData;
import com.yanfan.common.core.mq.message.FunctionCallBackBo;
import com.yanfan.common.core.thingsModel.ThingsModelSimpleItem;
import com.yanfan.common.exception.ServiceException;
import com.yanfan.common.utils.DateUtils;
import com.yanfan.common.utils.StringUtils;
import com.yanfan.iot.model.ThingsModels.ValueItem;
import com.yanfan.protocol.base.protocol.IProtocol;
import io.netty.buffer.Unpooled;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 健康手环协议解析
 *
 * @author lsy
 * @date 2022/10/10 16:55
 */
@Slf4j
@Component
@SysProtocol(name = "健康手环解析协议", protocolCode = YanfanConstant.PROTOCOL.JKSH, description = "健康手环解析协议")
public class BraceletProtocolService implements IProtocol {

    @Override
    public DeviceReport decode(DeviceData data, String clientId) {
        return null;
    }

    /**
     * 上报数据格式 <p>
     * [DW*334588000000156*00CD*UD,160918,025723,A,22.570733,N,113.8626083,E,0.00,249.5,0.0,6,100,60,0,00000010,7,255,460,1,9529,21809,158,9529,63555,133,9529,63554,129,9529,21405,126,9529,21242,124,9529,21151,120,9529,63556,119,0]
     */
    @Override
    public DeviceReport decode(DeviceData deviceData, String clientId, Session session) {
        try {
            DeviceReport reportMessage = new DeviceReport();
            // bytep[] 转String
            String dataString = new String(deviceData.getData(), StandardCharsets.UTF_8);
            log.info("【健康手环】-> 上报 msg: {}", dataString);
            String dataContent = dataString.substring(1, dataString.length() - 1);
            String[] msgs = dataContent.split("]\\[");
            String CHANGSHANG = null;
            for (String msg : msgs) {
                String[] split = msg.split(JkshUtil.SEPARATOR);
                // 判断厂商
                /*if (!Objects.equals(split[0], SIYAO + CHANGSHANG)) {
                    log.error("【健康手环】校验参数错误:" + data);
                    throw new ServiceException("【健康手环】校验参数错误:" + data);
                }*/

                // 判断厂商
                /*if (!split[0].contains(CHANGSHANG)) {
                    throw new ServiceException("【健康手环】校验参数错误:" + msg);
                }*/

                // 厂商
                CHANGSHANG = split[0];
                // 设备编号
                clientId = split[1];
                // 长度 * 2 是数据总长度
                int len = HexUtil.hexToInt(split[2]);
                // 数据体
                String body = split[3];
                if (len != body.length()) {
                    throw new ServiceException("【健康手环】数据长度校验错误:" + msg);
                }

                JSONObject obj = JkshUtil.getData(body);
                List<ThingsModelSimpleItem> values = new ArrayList<>();
                for (Map.Entry<String, Object> entry : obj.entrySet()) {
                    ThingsModelSimpleItem item = new ThingsModelSimpleItem();
                    item.setTs(DateUtils.getNowDate());
                    item.setValue(entry.getValue() + "");
                    item.setId(entry.getKey());
                    values.add(item);
                }
                //上报数据时间
                for (ThingsModelSimpleItem value : values) {
                    value.setTs(DateUtils.getNowDate());
                }
                reportMessage.setThingsModelSimpleItem(values);
                reportMessage.setClientId(clientId);
                reportMessage.setSerialNumber(clientId);
                reportMessage.setSources(msg);

                String cmd = obj.getString("cmd");
                if (JkshUtil.Type.getType(cmd).isReply()) {
                    if (Objects.nonNull(session)) {
                        // 响应的数据体
                        String respBody = cmd;
                        // DW*YYYYYYYYYYYYYYY*LEN*cmd
                        String resp = CHANGSHANG + "*" + clientId + "*" + String.format("%04x", respBody.length()) + "*" + respBody;
                        log.info("【健康手环】-> 下发 msg: {}", resp);
                        session.notify(Unpooled.buffer().writeBytes(resp.getBytes(StandardCharsets.UTF_8)));
                    }
                }
            }
            return reportMessage;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("【健康手环】数据解析异常: " + e.getMessage());
        }
    }


    /**
     * 下发 [{"id":"switch","value":"0","remark":""}]
     *
     * @param message
     * @return
     */
    @Override
    public FunctionCallBackBo encode(MQSendMessageBo message) {
        try {
            FunctionCallBackBo callBack = new FunctionCallBackBo();
            JSONObject params = message.getParams();
            ValueItem valueItem = new ValueItem();
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                valueItem.setId(entry.getKey());
                valueItem.setValue(entry.getValue() + "");
                valueItem.setRemark("");
            }
            String msg = "[" + JSONObject.toJSONString(valueItem) + "]";
            callBack.setSources(msg);
            callBack.setMessage(msg.getBytes());
            return callBack;
        } catch (Exception e) {
            log.error("【健康手环】=>指令编码异常,device={},data={}", message.getSerialNumber(), message.getParams());
            return null;
        }
    }

    public static void main(String[] args) {
        String baowen = "DW*334588000000156*0014*KA,120414,50,100,100,100.12";
        System.out.println(Arrays.toString(baowen.split("\\*")));
        System.out.println(HexUtil.hexToInt("FFFF"));
        System.out.println(HexUtil.hexToLong("FFFF"));
        System.out.println(HexUtil.hexToInt("00CD"));
        System.out.println(StrUtil.count(baowen, "*"));
        System.out.println(StringUtils.countMatches(baowen, "*"));

        String cmd = "cmdasfasfasfasfasgasgasgas";
        String resp = "DW*334588000000156*" + String.format("%04x", cmd.length()).toUpperCase() + "*" + cmd;
        System.out.println(resp);
    }
}
